"""
Interpretor.py -- converting XML information into C++ class representation. 

Contains helper class and functions allowing to read a XML file (with
the appropriate syntax) and translate the contained information into a
ClassRepresentation (from TypeDefinitions.py).
"""

##@package Interpretor
# Contains class wich allows to read an XML file and translate its
# content in a ClassRepresentation (from TypeDefinitions.py). It also
# contains a helper function which does upper- lowercase conversion.
#
# @author Johan "Solo" Luisier
# @date October 2011

from xml.dom import minidom, Node
from TypeDefinitions import *
from Translator import *
from CodeReader import *
from XmlCppClassGenerator.OutputStreams import OutputStream

import sys
import subprocess
import os.path

## Function which replaces the first letter of a given string by its
# lowercase version.
#
# @param[in] string string which will be changed.
#
# @return the given string with its first letter put in lowercase.
def lowerFirstLetter( string ) :
    return string[0].lower() + string[1:]

## Class implementing the conversion of an XML file into
## ClassRepresentation objects.
#
#
# Inherits from OutputStream so that nice output can be used.
#
# @author Johan "Solo" Luisier
# @date October 2011
class Interpretor( OutputStream ) :
    ## Constructor
    # Initialises the data members to default (and empty) values. The
    # header and implementation files extentions are '.hpp' and '.cpp'
    # respectively.
    #
    # @param[in] self reference on calling instance.
    def __init__( self ) :
        OutputStream.__init__( self )
        self.__XmlFileName = ''
        self.__XmlDomDocument  = None
        self.__Representations = []
        self.__HeaderExtension = '.hpp'
        self.__ImplementationExtension = '.cpp'
        self.__Translator = None
        self.__CodeReader = CodeReader()
        self.__FlagComment = []
    ## Allows to change the file name.
    #
    # @param[in] self reference on calling instance.
    # @param[in] fileName new value of XmlFileName.
    #
    # @return value of XmlFileName
    def setXmlFileName( self, fileName ) :
        self.__XmlFileName = fileName
        return self.__XmlFileName
    ## Allows to access the file name.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of XmlFileName
    def getXmlFileName( self ) :
        return self.__XmlFileName
    ## Allows to change the header file extension.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] headerExt new value of HeaderExtension
    #
    # @return the value of HeaderExtension
    def setHeaderExtension( self, headerExt ) :
        self.__HeaderExtension = headerExt
        return self.__HeaderExtension
    ## Allows to get the value of HeaderExtension.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the value of HeaderExtension
    def getHeaderExtension( self ) :
        return self.__HeaderExtension
    ## Allows to change the implementation file extension.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] implementationExt new value of ImplementationExtension
    #
    # @return the value of ImplementationExtension
    def setImplementationExtension( self, implementationExt ) :
        self.__ImplementationExtension = implementationExt
        return self.__ImplementationExtension
    ## Allows to get the value of ImplementationExtension.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the value of ImplementationExtension
    def getImplementationExtension( self ) :
        return self.__ImplementationExtension
    ## Allows to get the translation file read. This translation file
    # provides the bodies and comments of the getters / setters, and
    # the empty body for other methods.  
    #
    # Can terminate the execution if the file is corrupted, not
    # present, if neither the wanted language nor english can be
    # found.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] trans wanted language.
    def setTranslator( self, trans ) :
        self.__Translator = trans
    ## Allows to parse the (once the file name has bee set).
    #
    # @param[in] self reference on calling instance.
    #
    # @return 1 if the document does not have 'classes' as the root
    # node, 0 if it does.
    def loadDomTree( self ) :
        self.__XmlDomDocument = minidom.parse( self.__XmlFileName )
        self.__XmlDomRoot = self.__XmlDomDocument.documentElement
        if ( self.__XmlDomRoot.nodeName != 'classes' ) :
            print "Check your input file, 'classes' is not the root element"
            return 1
        return 0
    ## Reads through the whole DOM tree and looks for the 'class' DOM
    # element. For each of these, the construction of the
    # ClassRepresentation is delegated to the readAndLoadClass method.
    #
    # @param[in] self reference on calling instance.
    #
    # @return 0 if everything went fine and smoothly, or the error
    # code.
    def findClasses( self ) :
        retVal = 0
        for child in self.__XmlDomRoot.childNodes :
            if ( child.nodeName == 'class' ) :
                retVal = self.readAndLoadClass( child )
                if ( retVal != 0 ):
                    return retVal
        return retVal
    ## Creates a ClassRepresentation object from a '&lt;class&gt;'
    # element node. The children are read by dedicated functions. Once
    # created, the object is added to the __Representations array.
    #
    # @param[in] self reference on calling instance.
    # @param[in] node instance of node which node name is 'class'.
    #
    # @return the number of loaded class(es).
    def readAndLoadClass( self, node ) :
        back = ClassRepresentation()

        infoList = [ 'name',
                     'author',
                     'date',
                     'namespace',
                     'inherits',
                     'comments' ]

        commentFlag = True

        for child in node.childNodes :
            if ( child.nodeName == 'name' ) :
                back.setClassName( child.firstChild.nodeValue.strip() )
            if ( child.nodeName == 'namespace' ) :
                back.setNamespace( child.firstChild.nodeValue.strip() )
            elif ( child.nodeName == 'author' ) :
                back.setAuthor( child.firstChild.nodeValue.strip() )
            elif ( child.nodeName == 'date' ) :
                back.setDate( child.firstChild.nodeValue.strip() )
            elif ( child.nodeName == 'inherits' ) :
                attr = self.findAttributes( child )
                accType = 'public'
                if ( 'access' in attr ) :
                    loc = attr.index( 'access' )
                    accType = attr[ loc + 1 ]
                virtualStr = ''
                if ( 'virtual' in attr ) :
                    loc = attr.index( 'virtual' )
                    if ( attr[ loc + 1 ] == 'true' ) :
                        virtualStr = 'virtual'
                back.addInherits( child.firstChild.nodeValue.strip(), accType, virtualStr )
            elif ( child.nodeName == 'forwardDeclaration' ) :
                back.addForwardDeclaration( child.firstChild.nodeValue.strip() )
            elif ( child.nodeName == 'headerInclude' ) :
                attr = self.findAttributes( child )
                local = False
                if ( 'local' in attr ) :
                    loc = attr.index( 'local' )
                    if ( attr[ loc + 1 ] == 'true' ) :
                        local = True
                back.addHeaderInclude( child.firstChild.nodeValue.strip(), local )
            elif ( child.nodeName == 'implementationInclude' ) :
                attr = self.findAttributes( child )
                local = False
                if ( 'local' in attr ) :
                    loc = attr.index( 'local' )
                    if ( attr[ loc + 1 ] == 'true' ) :
                        local = True
                back.addImplementationInclude( child.firstChild.nodeValue.strip(), local )
            elif ( child.nodeName == 'headerUsedNamespace' ) :
                back.addUsingNamespace( child.firstChild.nodeValue.strip(), True )
            elif ( child.nodeName == 'implementationUsedNamespace' ) :
                back.addUsingNamespace( child.firstChild.nodeValue.strip(), False )
            elif ( child.nodeName == 'comments' ) :
                if ( child.firstChild.nodeValue.strip() == 'false' ) :
                    commentFlag == False
                    #self.__FlagComment = False
            elif ( child.nodeName == 'public' or child.nodeName == 'protected' or child.nodeName == 'private' ) :
                self.loopOnClassItems( back, child, child.nodeName )

        for constructor in back.getPublicConstructors() :
            self.addConstructorBody( back, constructor )
        for constructor in back.getProtectedConstructors() :
            self.addConstructorBody( back, constructor )
        for constructor in back.getPrivateConstructors() :
            self.addConstructorBody( back, constructor )

        for ( what, access ) in back.getAutomaticMethods().iteritems() :
            if ( what == 'copyConstructor' ) :
                self.addCopyConstructor( back, access )
            elif ( what == 'affectationOperator' ) :
                self.addAffectationOperator( back, access )
            elif ( what == 'comparisonOperator' ) :
                self.addComparisonOperator( back, access )

        self.addDestructor( back )
        
        self.__Representations.append( back )
        self.__FlagComment.append( commentFlag )

        return len( self.__Representations )
    ## Looks for the node which name corresponds to a wanted string,
    # and returns the value it contains.
    #
    # @param[in] self reference on calling instance.
    # @param[in] node instance of node for which the text node is
    # wanted.
    # @param[in] name name of the node of which the text node is
    # requested.
    #
    # @return what is contained in the text node, or '' if there is no
    # such node.
    def findNodeText( self, node, name ) :
        for child in node.childNodes :
            if ( child.nodeName == name ) :
                return child.firstChild.nodeValue
        return ''
    ## Looks for the nodes which names correpond to a wanted string,
    # and returns the values and attributes it contains.
    #
    # @param[in] self reference on calling instance.
    # @param[in] node instance of node for which the text node is
    # wanted.
    # @param[in] name name of the node of which the text node is
    # requested.
    #
    # @return an array containing the value contained in the wanted
    # node, followed by the found pairs of attribute name and
    # attribute value.
    def findNodesTextes( self, node, name ) :
        result = []
        for child in node.childNodes :
            if ( child.nodeName == name ) :
                result . append( child.firstChild.nodeValue )
                if ( child.hasAttributes() ) :
                    for ( name, value ) in child.attributes.items() :
                        result.append( name )
                        result.append( value )
        return result
    ## Looks for all the attributes of a given node, and returns the
    # name and values in an array.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] node instance of node for which the attributes have
    # to be collected.
    #
    # @return an array containing the serie of attribute name/ value,
    # ...
    def findAttributes( self, node ) :
        results = []
        if ( node.hasAttributes() ) :
            for ( name, value ) in node.attributes.items() :
                results.append( name )
                results.append( value )
        return results
    ## Loops on element nodes children of 'public', 'protected' or
    # 'private' node, and calls the appropriate function to interpret
    # the found nodes.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] node instance of node (i.e. 'public', 'protected' or
    # 'private').
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def loopOnClassItems( self, representation, node, access ) :
        for child in node.childNodes :
            if ( child.nodeName == 'constructor' ) :
               self.addConstructor( representation, child, access )
            elif ( child.nodeName == 'copyConstructor' or \
                       child.nodeName == 'affectationOperator' or \
                       child.nodeName == 'comparisonOperator' ) :
                if ( child.firstChild.nodeValue.strip() == 'true' ) :
                    self.addSpecialMethod( representation, child.nodeName, access )
            elif ( child.nodeName == 'method' ) :
               self.addMethod( representation, child, access )
            elif ( child.nodeName == 'member' ) :
               self.addMember( representation, child, access )
    ## Adds a special method
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] what name of the item which will be added.
    # @param[in] access access specifier of the item.
    def addSpecialMethod( self, representation, what, access ) :
        methodName = self.__Translator.getInformationString( what )[0]
        if ( not representation.addAutomaticMethod( what, access ) ) :
            # Get this from the message XML file.
            message = self.__Translator.getInformationMessage( 'alreadyPresent' )[0]
            self.warning( message.format( methodName, representation.getClassName() ) )
            return
        message = self.__Translator.getInformationMessage( 'genMethod' )[0]
        self.verbose( message.format( access, methodName, representation.getClassName() ) )
    ## Adds a constructor to the given %ClassRepresentation.
    # The needed information is read and an instance of
    # %ConstructorRepresentation is built then added to the correct
    # container, depending on the access type.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] node instance of node (i.e. 'constructor').
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def addConstructor( self, representation, node, access ) :
        message = self.__Translator.getInformationMessage( 'addItem' )[0]
        what = self.__Translator.getInformationString( 'constructor' )[0]
        self.verbose( message.format( access, what ) )
        newConstructor = ConstructorRepresentation()
        newConstructor.setName( representation.getClassName() )
        for child in node.childNodes :
            if ( child.nodeName == 'argument' ) :
                newConstructor.addArgument( self.readArgument( child ) )
        
        comments = newConstructor.produceComment()
        message = self.__Translator.getInformationString( 'constructor' )[0]
        comments = comments.format( message.capitalize() )
        newConstructor.setComments( comments )

        if ( access == 'public' ) :
            representation.addPublicConstructor( newConstructor )
        elif ( access == 'protected' ) :
            representation.addProtectedConstructor( newConstructor )
        elif ( access == 'private' ) :
            representation.addPrivateConstructor( newConstructor )
    ## Adds the body to the constructors, once the %ClassRepresentation
    # is fully initialised.
    #
    # A body is added to the constructor. This body contains the 
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] constructor instance of constructor to be processed.
    def addConstructorBody( self, representation, constructor ) :
        if ( constructor.getBody() != '' ) : return
        body = str()
        if ( len( representation.getInherits() ) > 0 ) :
            body = ' : '
            for array in representation.getInherits() :
                body += array[ 0 ] + '( ),\n'
        if ( representation.getNbrNonStaticMembers() > 0 ) :
            if ( body == '' ) : body = ' : '
            body += '{}( ),\n' * representation.getNbrNonStaticMembers()
            body = body[:-2]
            body += '\n'
            body = body.format( *representation.getNonStaticMembers() )
            body += self.__CodeReader.getInformationBody( 'empty' )[0]
            body = body.replace( '\\n', '\n' )
            constructor.setBody( body )
        else :
            body += self.__CodeReader.getInformationBody( 'empty' )[0]
            body = body.replace( '\\n', '\n' )
            constructor.setBody( body )
    ## Adds a copy constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def addCopyConstructor( self, representation, access ) :
        message = "Will add a {0} copy constructor."
        self.verbose( message.format( access ) )
        copyConstructor = ConstructorRepresentation()
        copyConstructor.setName( representation.getClassName() )
        newArgument = ArgumentRepresentation()
        newArgument.setTypeName( representation.getClassName() )
        newArgument.setReference( True )
        newArgument.setConstness( True )
        newArgument.setName( lowerFirstLetter( representation.getClassName() ) )
        copyConstructor.addArgument( newArgument )

        argName = newArgument.getName()

        body = str()
        if ( len( representation.getInherits() ) > 0 ) :
            body = ' : '
            for array in representation.getInherits() :
                body += array[ 0 ] + '( {0} ),\n'.format( argName )
        if ( representation.getNbrNonStaticMembers() > 0 ) :
            if ( body == '' ) : body = ' : '
            body += '{}( ),\n' * representation.getNbrNonStaticMembers()
            body = body[:-2]
            body += '\n'
            memberList = representation.getNonStaticMembers()
            body = body.format( *memberList )
            body = body.replace( '( )', '( {} )' )
            memberList = [ argName + '.' + lowerFirstLetter( obj ) + '()' for obj in memberList ]
            #for index, obj in enumerate( memberList ) :
            #memberList[ index ] = argName + '.' + lowerFirstLetter( obj ) + '()'
            body = body.format( *memberList )
            body += self.__CodeReader.getInformationBody( 'empty' )[0]
            body = body.replace( '\\n', '\n' )
            copyConstructor.setBody( body )
        else :
            if ( body != '' ) :
                body = body[:-2] + '\n'
            body += self.__CodeReader.getInformationBody( 'empty' )[0]
            body = body.replace( '\\n', '\n' )
            copyConstructor.setBody( body )
        
        if ( access == 'public' ) :
            representation.addPublicConstructor( copyConstructor )
        elif ( access == 'protected' ) :
            representation.addProtectedConstructor( copyConstructor )
        elif ( access == 'private' ) :
            representation.addPrivateConstructor( copyConstructor )
    ## Adds a copy constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def addAffectationOperator( self, representation, access ) :
        message = "Will add a {0} affectation operator."
        self.verbose( message.format( access ) )
        affectation = MethodRepresentation()
        affectation.setName( 'operator=' )
        newArgument = ArgumentRepresentation()
        newArgument.setTypeName( representation.getClassName() )
        newArgument.setReference( True )
        newArgument.setConstness( True )
        newArgument.setName( lowerFirstLetter( representation.getClassName() ) )
        affectation.addArgument( newArgument )
        affectation.setTypeName( representation.getClassName() )
        affectation.setReference( True )

        argName = newArgument.getName()

        body = '{\n'
        if ( len( representation.getInherits() ) > 0 ) :
            for array in representation.getInherits() :
                body += 'this -> ' + array[ 0 ] + '::operator=( {0} );\n'.format( argName )
        if ( representation.getNbrNonStaticMembers() > 0 ) :
            rawLine = '{0} = {1}.{2}();\n'
            for member in representation.getNonStaticMembers() :
                body += rawLine.format( member, argName, lowerFirstLetter( member ) )
        body += 'return *this;\n'
        body += '}\n'
        affectation.setBody( body )

        if ( access == 'public' ) :
            representation.addPublicMethod( affectation )
        elif ( access == 'protected' ) :
            representation.addProtectedMethod( affectation )
        elif ( access == 'private' ) :
            representation.addPrivateMethod( affectation )
    ## Adds a copy constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def addComparisonOperator( self, representation, access ) :
        message = "Will add a {0} comparison operator."
        self.verbose( message.format( access ) )
        comparison = MethodRepresentation()
        comparison.setName( 'operator==' )
        newArgument = ArgumentRepresentation()
        newArgument.setTypeName( representation.getClassName() )
        newArgument.setReference( True )
        newArgument.setConstness( True )
        newArgument.setName( lowerFirstLetter( representation.getClassName() ) )
        comparison.addArgument( newArgument )
        comparison.setTypeName( 'bool' )
        comparison.setReference( False )
        comparison.setFunctionConstness( True )

        argName = newArgument.getName()

        body = '{\n'
        if ( len( representation.getInherits() ) > 0 ) :
            rawLine = 'if ( ! this -> {0}::operator==( {1} ) )\n return false;\n'
            for array in representation.getInherits() :
                body += rawLine.format( array[0], argName )
        body += 'if ( '
        if ( representation.getNbrNonStaticMembers() > 0 ) :
            rawLine = '{0} == {1}.{2}() &&\n'
            for member in representation.getNonStaticMembers() :
                body += rawLine.format( member, argName, lowerFirstLetter( member ) )
        body = body[:-3]
        body += ')\n return true;\n'
        body += 'return false;\n'
        body += '}\n'
        comparison.setBody( body )

        if ( access == 'public' ) :
            representation.addPublicMethod( comparison )
        elif ( access == 'protected' ) :
            representation.addProtectedMethod( comparison )
        elif ( access == 'private' ) :
            representation.addPrivateMethod( comparison )
    ## Adds a destructor to the given %ClassRepresentation.
    # The name is constructed from the class name, the body and the
    # comments are retrieved from the __CodeReader and __Translator
    # objects.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which a (public) destructor will be added.
    def addDestructor( self, representation ) :
        destructor = ConstructorRepresentation()
        destructor.setName( '~' + representation.getClassName() )
        destructor.setBody( self.__CodeReader.getInformationBody( 'empty' )[0].replace( '\\n', '\n' ) )
        comments = destructor.produceComment()
        destructor.setVirtual( True )
        message = self.__Translator.getInformationString( 'destructor' )[0]
        comments = comments.format( message.capitalize() )
        destructor.setComments( comments )
        representation.addPublicConstructor( destructor )
    ## Adds a method to the given %ClassRepresentation.
    # The needed information is read and an instance of
    # %MethodRepresentation is built then added to the correct
    # container, depending on the access type.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] node instance of node (i.e. 'method').
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').
    def addMethod( self, representation, node, access ) :
        message = self.__Translator.getInformationMessage( 'addItem' )[0]
        what = self.__Translator.getInformationString( 'method' )[0]
        self.verbose( message.format( access, what ) )
        newMethod = MethodRepresentation()
        body = self.__CodeReader.getInformationBody( 'empty' )[0]
        body = body.replace( '\\n', '\n' )
        newMethod.setBody( body )
        for child in node.childNodes :
            if ( child.nodeName == 'return' ) :
                attrs = self.findAttributes( child )
                loc = attrs.index( 'type' )
                newMethod.setTypeName( attrs[ loc + 1 ] )
                if ( 'const' in attrs ) :
                    loc = attrs.index( 'const' )
                    if ( attrs[ loc + 1 ] == 'true' ) :
                        newMethod.setConstness( True )
                if ( 'ref' in attrs ) :
                    loc = attrs.index( 'ref' )
                    if ( attrs[ loc + 1 ] == 'true' ) :
                        newMethod.setReference( True )
                if ( 'ptr' in attrs ) :
                    loc = attrs.index( 'ptr' )
                    if ( attrs[ loc + 1 ] == 'true' ) :
                        newMethod.setPointer( True )
            elif ( child.nodeName == 'name' ) :
                newMethod.setName( child.firstChild.nodeValue.strip() )
            elif ( child.nodeName == 'argument' ) :
                newMethod.addArgument( self.readArgument( child ) )
            elif ( child.nodeName == 'const' ) :
                if ( child.firstChild.nodeValue.strip() == 'true' ) :
                    newMethod.setFunctionConstness( True )
        if ( access == 'public' ) :
            representation.addPublicMethod( newMethod )
        elif ( access == 'protected' ) :
            representation.addProtectedMethod( newMethod )
        elif ( access == 'private' ) :
            representation.addPrivateMethod( newMethod )
    ## Adds a method to the given %ClassRepresentation.
    # The needed information is read and an instance of
    # %MemberRepresentation is built then added to the correct
    # container, depending on the access type.
    #
    # If the std / ptr getter or setter is enabled, the corresponding
    # method(s) are added to the public method container.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] representation instance of ClassRepresentation to
    # which the found item will be added.
    # @param[in] node instance of node (i.e. 'member').
    # @param[in] access access specifier (i.e. 'public', 'protected' or
    # 'private').    
    def addMember( self, representation, node, access ) :
        message = self.__Translator.getInformationMessage( 'addItem' )[0]
        what = self.__Translator.getInformationString( 'member' )[0]
        self.verbose( message.format( access, what ) )
        newMember = MemberRepresentation()
        newMember.setName( node.firstChild.nodeValue.strip() )
        attrs = self.findAttributes( node )
        loc = attrs.index( 'type' )
        newMember.setTypeName( attrs[ loc + 1 ] )
        if ( 'const' in attrs ) :
            loc = attrs.index( 'const' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setConstness( True )
        if ( 'ref' in attrs ) :
            loc = attrs.index( 'ref' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setReference( True )
        if ( 'ptr' in attrs ) :
            loc = attrs.index( 'ptr' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setPointer( True )
        if ( 'static' in attrs ) :
            loc = attrs.index( 'static' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setStatic( True )
        if ( 'value' in attrs ) :
            loc = attrs.index( 'value' )
            newMember.setValue( attrs[ loc + 1 ] )

        newMember.setStdGet( True )
        newMember.setStdSet( True )
        newMember.setPtrGet( False )
        newMember.setPtrSet( False )

        if ( 'stdGet' in attrs ) :
            loc = attrs.index( 'stdGet' )
            if ( attrs[ loc + 1 ] == 'false' ) :
                newMember.setStdGet( False )
        if ( 'stdSet' in attrs ) :
            loc = attrs.index( 'stdSet' )
            if ( attrs[ loc + 1 ] == 'false' ) :
                newMember.setStdSet( False )
        if ( 'ptrGet' in attrs ) :
            loc = attrs.index( 'ptrGet' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setPtrGet( True )
        if ( 'ptrSet' in attrs ) :
            loc = attrs.index( 'ptrSet' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newMember.setPtrSet( True )

        if ( newMember.getConstness() ) :
            newMember.setStdSet( False )
            newMember.setPtrSet( False )

        if ( newMember.getStdGet() == True ) :
            message = self.__Translator.getInformationMessage( 'genMethod' )[0]
            what = self.__Translator.getInformationString( 'getter' )[0]
            self.verbose( message.format( 'std', what, newMember.getName() ) )
            newMethodStdGet = MethodRepresentation()
            newMethodStdGet.setTypeName( newMember.getTypeName() )
            newMethodStdGet.setReference( True )
            newMethodStdGet.setConstness( True )
            newMethodStdGet.setFunctionConstness( True )
            newMethodStdGet.setName( lowerFirstLetter( newMember.getName() ) )
            string = self.__CodeReader.getInformationBody( 'stdGetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName() )
            newMethodStdGet.setBody( '{\n ' + string + '\n}\n' )
            string = self.__Translator.getInformationComment( 'stdGetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName() )
            newMethodStdGet.setComments( string )
            representation.addPublicMethod( newMethodStdGet )
        if ( newMember.getStdSet() == True ) :
            message = self.__Translator.getInformationMessage( 'genMethod' )[0]
            what = self.__Translator.getInformationString( 'setter' )[0]
            self.verbose( message.format( 'std', what, newMember.getName() ) )
            newMethodStdSet = MethodRepresentation()
            newMethodStdSet.setTypeName( 'void' )
            newMethodStdSet.setName( 'set' + newMember.getName() )
            string = self.__CodeReader.getInformationBody( 'stdSetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName(), lowerFirstLetter( newMember.getName() ) )
            newMethodStdSet.setBody( '{\n ' + string + '\n}\n' )
            string = self.__Translator.getInformationComment( 'stdSetter' )[0]
            string = string.format( newMember.getName(), lowerFirstLetter( newMember.getName() ) )
            string = string.replace( '\\n', '\n' )
            newMethodStdSet.setComments( string )
            newArgument = ArgumentRepresentation()
            newArgument.setTypeName( newMember.getTypeName() )
            newArgument.setReference( True )
            newArgument.setConstness( True )
            newArgument.setName( lowerFirstLetter( newMember.getName() ) )
            newMethodStdSet.addArgument( newArgument )
            representation.addPublicMethod( newMethodStdSet )
        if ( newMember.getPtrGet() == True ) :
            message = self.__Translator.getInformationMessage( 'genMethod' )[0]
            what = self.__Translator.getInformationString( 'getter' )[0]
            self.verbose( message.format( 'ptr', what, newMember.getName() ) )
            newMethodPtrGet = MethodRepresentation()
            newMethodPtrGet.setTypeName( newMember.getTypeName() )
            string = self.__CodeReader.getInformationBody( 'ptrGetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName() )
            newMethodPtrGet.setBody( '{\n ' + string + '\n}\n' )
            string = self.__Translator.getInformationComment( 'ptrGetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName() )
            newMethodPtrGet.setComments( string )
            newMethodPtrGet.setPointer( True )
            newMethodPtrGet.setConstness( True )
            newMethodPtrGet.setFunctionConstness( True )
            newMethodPtrGet.setName( lowerFirstLetter( newMember.getName() ) + 'Ptr' )
            representation.addPublicMethod( newMethodPtrGet )
        if ( newMember.getPtrSet() == True ) :
            message = self.__Translator.getInformationMessage( 'genMethod' )[0]
            what = self.__Translator.getInformationString( 'setter' )[0]
            self.verbose( message.format( 'ptr', what, newMember.getName() ) )
            newMethodPtrSet = MethodRepresentation()
            newMethodPtrSet.setTypeName( 'void' )
            newMethodPtrSet.setName( 'set' + newMember.getName() + 'Ptr' )
            string = self.__CodeReader.getInformationBody( 'ptrSetter' )[0]
            string = string.replace( '\\n', '\n' )
            string = string.format( newMember.getName(), lowerFirstLetter( newMember.getName() ) )
            newMethodPtrSet.setBody( '{\n ' + string + '\n}\n' )
            string = self.__Translator.getInformationComment( 'ptrSetter' )[0]
            string = string.format( newMember.getName(), lowerFirstLetter( newMember.getName() ) )
            string = string.replace( '\\n', '\n' )
            newMethodPtrSet.setComments( string )
            newArgument = ArgumentRepresentation()
            newArgument.setTypeName( newMember.getTypeName() )
            newArgument.setPointer( True )
            newArgument.setName( lowerFirstLetter( newMember.getName() ) )
            newMethodPtrSet.addArgument( newArgument )
            representation.addPublicMethod( newMethodPtrSet )

        if ( access == 'public' ) :
            representation.addPublicMember( newMember )
        elif ( access == 'protected' ) :
            representation.addProtectedMember( newMember )
        elif ( access == 'private' ) :
            representation.addPrivateMember( newMember ) 
    ## Reads an argument (of a method or constructor).
    #
    # @param[in] self reference on the calling instance.
    # @param[in] node instance of 'argument' node.
    #
    # @return a new instance of %ArgumentRepresentation.
    def readArgument( self, node ) :
        newArgument = ArgumentRepresentation()
        newArgument.setName( node.firstChild.nodeValue.strip() )
        attrs = self.findAttributes( node )
        loc = attrs.index( 'type' )
        newArgument.setTypeName( attrs[ loc + 1 ] )
        if ( 'const' in attrs ) :
            loc = attrs.index( 'const' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newArgument.setConstness( True )
        if ( 'ref' in attrs ) :
            loc = attrs.index( 'ref' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newArgument.setReference( True )
        if ( 'ptr' in attrs ) :
            loc = attrs.index( 'ptr' )
            if ( attrs[ loc + 1 ] == 'true' ) :
                newArgument.setPointer( True )
        if ( 'default' in attrs ) :
            loc = attrs.index( 'default' )
            newArgument.setDefault( attrs[ loc + 1 ] )
        
        return newArgument
    ## Writes the header file of the classes read from the XML file.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] outputDir output directory path.
    def writeHeaderFile( self, outputDir='./' ) :
        for index, classRep in enumerate( self.__Representations ) :

            headerFileName = outputDir + '/' + classRep.getClassName()
            headerFileName += self.getHeaderExtension()

            HeaderFile = self._safeFileOpening( headerFileName )

            # ifndef preproc line :
            preproc = '#ifndef ' + classRep.getClassName().upper()
            preproc += self.getHeaderExtension().replace( '.', '_' ).upper() + '\n'
            HeaderFile.write( preproc )

            # define preproc line :
            preproc = '#define ' + classRep.getClassName().upper()
            preproc += self.getHeaderExtension().replace( '.', '_' ).upper() + '\n'
            HeaderFile.write( preproc + '\n' )

            # user file includes
            templateLine = '#include "{}"\n'

            if ( len( classRep.getHeaderInclude( True ) ) > 0 ) :
                for include in classRep.getHeaderInclude( True ) :
                    HeaderFile.write( templateLine.format( include ) )

                HeaderFile.write( "\n" )

            # system file includes
            templateLine = "#include <{}>\n"

            if ( len( classRep.getHeaderInclude( False ) ) > 0 ) :
                for include in classRep.getHeaderInclude( False ) :
                    HeaderFile.write( templateLine.format( include ) )

                HeaderFile.write( "\n" )

            # using namespace lines
            templateLine = 'using namespace {};\n'

            if ( len( classRep.getUsingNamespace( True ) ) > 0 ) :
                for using in classRep.getUsingNamespace( True ) :
                    HeaderFile.write( templateLine.format( using ) )

                HeaderFile.write( "\n" )

            # forward declarations
            if ( len( classRep.getForwardDeclaration() ) > 0 ) :
                for forward in classRep.getForwardDeclaration() :
                    HeaderFile.write( forward + ';\n' )

                HeaderFile.write( "\n" )

            classRep.writeHeader( HeaderFile, self.__FlagComment[ index ] )

            # endif preproc line :
            preproc = '\n\n#endif // ' + classRep.getClassName().upper()
            preproc += self.getHeaderExtension().replace( '.', '_' ).upper() + '\n'
            HeaderFile.write( preproc )

            HeaderFile.close()
    ## Writes the implementation file of the classes read from the XML
    # file.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] outputDir output directory path.
    def writeImplementationFile( self, outputDir='./' ) :
        for classRep in self.__Representations :

            implementationFileName = outputDir + '/' + classRep.getClassName()
            implementationFileName += self.getImplementationExtension()

            ImplementationFile = self._safeFileOpening( implementationFileName )
            
            ImplementationFile.write( '#include "' + classRep.getClassName() + self.getHeaderExtension() + '"\n\n' )

            # user file includes
            templateLine = '#include "{}"\n'

            if ( len( classRep.getImplementationInclude( True ) ) > 0 ) :
                for include in classRep.getImplementationInclude( True ) :
                    ImplementationFile.write( templateLine.format( include ) )

                ImplementationFile.write( "\n" )

            # system file includes
            templateLine = "#include <{}>\n"

            if ( len( classRep.getImplementationInclude( False ) ) > 0 ) :
                for include in classRep.getImplementationInclude( False ) :
                    ImplementationFile.write( templateLine.format( include ) )

                ImplementationFile.write( "\n" )

            # using namespace lines
            templateLine = 'using namespace {};\n'

            if ( len( classRep.getUsingNamespace( False ) ) > 0 ) :
                for using in classRep.getUsingNamespace( False ) :
                    ImplementationFile.write( templateLine.format( using ) )

                ImplementationFile.write( "\n" )

            classRep.writeImplementation( ImplementationFile )
        
            ImplementationFile.close()
    ## Checks whether a file exists. If yes, the present file is saved
    # to a '.BAK' file and the new one is opened.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] fileName name of the file which will be opened.
    #
    # @return the opened file.
    def _safeFileOpening( self, fileName ) :
        if ( os.path.exists( fileName ) ) :
            message = self.__Translator.getInformationMessage( 'objExist' )[0]
            self.verbose( message.format( fileName ) )
            if ( os.path.isfile( fileName ) ) :
                message = self.__Translator.getInformationMessage( 'moveInfo' )[0]
                self.info( message.format( fileName ) )
                message = self.__Translator.getInformationMessage( 'objIsFile' )[0]
                self.verbose( message.format( fileName ) )
                command = [ 'mv', fileName, fileName + '.BAK' ]
                subprocess.call( command )

        try :
            File = open( fileName, 'w' )
        except IOError, ( errno, strerror ) :
            print fileName
            message = self.__Translator.getInformationMessage( 'ioError' )[0]
            self.fatal( message.format( errno, strerror ) )
            sys.exit( 1 )

        return File
        
